/*
 * Copyright (c) 2013-2015 Charkey. All rights reserved.
 *
 * This software is the confidential and proprietary information of Charkey.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the agreements you entered into with Charkey.
 *
 * Charkey MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 *
 * Charkey SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package cn.simastudio.talos.core.service.base.impl;

import cn.simastudio.talos.common.constants.SimaConstants;
import cn.simastudio.talos.core.exception.biz.ConstraintCheckException;
import cn.simastudio.talos.core.exception.biz.DataDeleteException;
import cn.simastudio.talos.core.exception.biz.DataInsertException;
import cn.simastudio.talos.core.exception.biz.DataUpdateException;
import cn.simastudio.talos.core.mapper.base.RoleMapper;
import cn.simastudio.talos.core.mapper.base.RoleResRelMapper;
import cn.simastudio.talos.core.mapper.base.UserRoleRelMapper;
import cn.simastudio.talos.core.model.base.Resource;
import cn.simastudio.talos.core.model.base.Role;
import cn.simastudio.talos.core.model.base.RoleResRel;
import cn.simastudio.talos.core.model.base.UserRoleRel;
import cn.simastudio.talos.core.service.base.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@SuppressWarnings("SpringJavaAutowiringInspection")
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleResRelMapper roleResRelMapper;

    @Autowired
    private UserRoleRelMapper userRoleRelMapper;

    @Override
    public Set<String> getRolesByUsername(String username) {
        List<Role> roleList = roleMapper.getRolesByUsername(username);
        return roleList.stream().map(Role::getName).collect(Collectors.toSet());
    }

    @Override
    public Role createRole(Role role) {
        int createRes = roleMapper.insertSelective(role);
        if (createRes != SimaConstants.DEFAULT_UPDATE_COUNT) {
            throw new DataInsertException();
        }
        List<Resource> resources = role.getResources();
        if (resources.size() > 0) {
            int batchInsertRes = roleResRelMapper.insertBatch(resources, role.getId());
            if (batchInsertRes <= 0) {
                throw new DataInsertException();
            }
        }
        return role;
    }

    @Override
    public boolean updateRole(Role role) {
        List<Resource> resources = role.getResources();
        if (resources.size() == 0) {
            int updateRes = roleMapper.updateByPrimaryKeySelective(role);
            if (updateRes != SimaConstants.DEFAULT_UPDATE_COUNT) {
                throw new DataUpdateException();
            }
        } else {
            List<RoleResRel> roleResRels = roleResRelMapper.getRoleResRelListByRoleId(role.getId());
            if (roleResRels.size() > 0) {
                int deleteRes = roleResRelMapper.deleteBatch(roleResRels);
                if (deleteRes <= 0) {
                    throw new DataDeleteException();
                }
            }
            int batchInsertRes = roleResRelMapper.insertBatch(role.getResources(), role.getId());
            if (batchInsertRes <= 0) {
                throw new DataInsertException();
            }
        }
        return true;
    }

    @Override
    public boolean deleteRole(Role role) {
        // 查询当前待删除的角色是否配置给某些用户，如有则不能删除此角色
        List<UserRoleRel> userRoleRelList = userRoleRelMapper.getUserRoleRelListByRoleId(role.getId());
        if (userRoleRelList.size() > 0) {
            throw new ConstraintCheckException();
        }
        // 删除配置给当前待删除角色的资源
        List<RoleResRel> roleResRels = roleResRelMapper.getRoleResRelListByRoleId(role.getId());
        if (roleResRels.size() > 0) {
            int deleteBatchRes = roleResRelMapper.deleteBatch(roleResRels);
            if (deleteBatchRes <= 0) {
                throw new DataDeleteException();
            }
        }
        // 删除当前待删除角色
        int deleteRes = roleMapper.deleteByPrimaryKey(role.getId());
        if (deleteRes != SimaConstants.DEFAULT_DELETE_COUNT) {
            throw new DataDeleteException();
        }
        return true;
    }

    @Override
    public Role getRole(Integer roleId) {
        return roleMapper.getRoleWithResources(roleId);
    }

    @Override
    public List<Role> getAllRolesWithResources() {
        return roleMapper.getAllRolesWithResources();
    }

    @Override
    public List<Role> getRoles(Integer[] roleIds) {
        if (roleIds.length == 0) {
            return null;
        }
        return roleMapper.getRolesWithResourcesByRoleIds(roleIds);
    }

}
